package cn.lijia.itrip.service.impl;

import cn.lijia.itrip.common.*;
import cn.lijia.itrip.exception.ItripException;
import cn.lijia.itrip.model.ItripUser;
import cn.lijia.itrip.service.TokenService;
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 李嘉
 * @create 2018-08-29-12:10
 */
@Service("tokenService")
public class TokenServiceImpl implements TokenService {

    @Resource
    private RedisAPI redisAPI;

    @Resource
    private ValidationUtil validationUtil;

    @Override
    public String generateToken(ItripUser itripUser, String userAgent) {
        StringBuffer sbToken = new StringBuffer("token:");
        if (UserAgentUtil.CheckAgent(userAgent)) {
            sbToken.append("MOBILE-");
        }else{
            sbToken.append("PC-");
        }
        sbToken.append(DigestUtil.hmacSign(itripUser.getUserCode())+"-");
        sbToken.append(itripUser.getId()+"-");
        //创建时间
        String dateTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        sbToken.append(dateTime+"-");
        //userAgent 加密取前六位
        String md5UserAgent = DigestUtil.hmacSign(userAgent).substring(0, 6);
        sbToken.append(md5UserAgent);
        return sbToken.toString();
    }

    @Override
    public void saveToken(String token, ItripUser itripUser) {
        String itripUserJSON = JSON.toJSONString(itripUser);

        if(token.indexOf("PC") != -1){
            //如果是PC端，保存2小时
            redisAPI.set(token,itripUserJSON,60*60*2);
        }else {
            redisAPI.set(token,itripUserJSON);
        }

    }

    @Override
    public Boolean exists(String token) {
        return redisAPI.exists(token);
    }

    @Override
    public Boolean del(String token) {
//        if(redisAPI.del(token) == 1){
//            return true;
//        }
        return redisAPI.del(token) == 1 ? true : false;
    }

    @Override
    public String retoken(String token, String userAgent) throws ItripException {
        //验证Token是否有效
        if (!this.validateToken(token,userAgent)) {
            throw new ItripException("token失效",ErrorCode.AUTH_TOKEN_INVALID);
        }
        try {
            //能不能够置换，是否处在保护期
            long currentTime = System.currentTimeMillis();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            long createTime = sdf.parse(token.split("-")[3]).getTime();
            //保护期 一个小时
            //int productTime = 1000 * 60 * 60 * 1;
            int productTime = 1;
            if (currentTime -createTime < productTime) {
                throw new ItripException("Token处于保护期，无法置换",ErrorCode.AUTH_REPLACEMENT_FAILED);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //判断token剩余过期时间
        Long ttl = redisAPI.ttl(token);
        //进行置换,兼容移动端和PC端
        if (ttl > 0 || ttl == -1) {
            //旧的token延迟过期
            redisAPI.expire(token,60 * 3);
            //新的token保存到Redis
            ItripUser user = validationUtil.getUser(token);

            String newToken = this.generateToken(user, userAgent);
            //保存token
            this.saveToken(newToken,user);
            return  newToken;
        }else {
            throw new ItripException("token失效",ErrorCode.AUTH_TOKEN_INVALID);
        }
    }

    @Override
    public Boolean validateToken(String token, String userAgent) {
        //判断token是否存在

        if(!this.exists(token)){
            return false;
        }
        //判断登录浏览器和退出浏览器是否一致
       // String userAgent = request.getHeader("user-agent");
        String md5UserAgent = DigestUtil.hmacSign(userAgent).substring(0, 6);
        if(!token.split("-")[4].equals(md5UserAgent)){
            return false;
        }
        return true;
    }
}
